#include <file.au3>
#include <array.au3>

Global $USER = "skt90u"
Global $PASS = "490410056"
Global $HOST = "csie0.cs.ccu.edu.tw"
Global $DefaultIsInstall = 1

Global $InstallImplFunc = "InstallImpl"
Global $UninstallImplFunc = "UninstallImpl"
Global $SleepDelay = 50
Global $RemoveAfterInstallSuccess = False

Func Main($InstallProgramPath, $InstallFolder, $SetupFile, $UninstallPath)
	Dim $numParam = $CmdLine[0]
	
	Dim $Action = GetDefaultAction()
	If $numParam > 0 Then
		If StringCompare ( "Install", $CmdLine[1]) = 0  Or StringCompare ( "Uninstall", $CmdLine[1]) = 0 Then
			$Action = $CmdLine[1]
		EndIf
	EndIf

	Switch $Action
		Case "Install"
			logInfo("Main", "Call(" & $Action & ", " & $InstallProgramPath & ", " & $InstallFolder & ", " & $SetupFile & ")")
			$retVal = Call($Action, $InstallProgramPath, $InstallFolder, $SetupFile)
		Case "Uninstall"
			logInfo("Main", "Call(" & $Action & ", " & $UninstallPath & ")")
			$retVal = Call($Action, $UninstallPath)
		Case Else
			logError("Main", "Unknown Action :" & $Action)
			$retVAl = 0
	EndSwitch

	If @error = 0xDEAD Then
		logError("Main", "Function '" & $Action & "' does not exist or invalid number of parameters in " & @ScriptName)
		Exit
	EndIf
	
	Return $retVal
EndFunc	

Func Install($InstallProgramPath,$InstallFolder, $SetupFile)
	If Not CheckSetupFile($SetupFile) Then
		Return False
	EndIf

	If Not CheckBeforeInstall($InstallProgramPath, $InstallFolder) Then
		Return False
	EndIf
		
	Dim $SetupPath = GetSetupPath($SetupFile)
	
	Dim $ImplFunc = $InstallImplFunc
	; All that you need to do is implement a function to handle your automatic installation process 
	$retVal = Call($ImplFunc, $SetupPath)
	;Sets @error to 0xDEAD and @extended to 0xBEEF if the function does not exist or invalid number of parameters
	If @error = 0xDEAD Then
		logError("Install", "Function '" & $ImplFunc & "' does not exist or invalid number of parameters in " & @ScriptName)
		Exit
	EndIf

	If $retVal And $RemoveAfterInstallSuccess Then
		FileDelete($SetupPath)
	EndIf

	Return $retVal
EndFunc

Func Uninstall($UninstallPath)
	If StringLen($UninstallPath) <> 0 And Not FileExists($UninstallPath) Then
		logError("Uninstall", "uninstall program doesn't exist (" & $UninstallPath & ")")
		Return False
	EndIf
	
	Dim $ImplFunc = $UninstallImplFunc
	; All that you need to do is implement a function to handle your automatic installation process 
	$retVal = Call($ImplFunc, $UninstallPath)
	;Sets @error to 0xDEAD and @extended to 0xBEEF if the function does not exist or invalid number of parameters
	If @error = 0xDEAD Then
		logError("Install error", "Function '" & $ImplFunc & "' does not exist or invalid number of parameters in " & @ScriptName)
		Exit
	EndIf
	Return $retVal
EndFunc



Func RunSetupFile($SetupPath)
	Dim $szDrive, $szDir, $szFName, $szExt
	_PathSplit($SetupPath, $szDrive, $szDir, $szFName, $szExt)
	
	If StringCompare (".exe", $szExt) = 0  Then
		Return Run($SetupPath)
	EndIf
		
	If StringCompare (".msi", $szExt) = 0  Then
		Return ShellExecute($SetupPath)
	EndIf
	
	If StringInStr($SetupPath, ".exe") <> 0 Then
		Return Run($SetupPath)
	EndIf
	
	If StringInStr($SetupPath, ".msi") <> 0 Then
		Return ShellExecute($SetupPath)
	EndIf

	logError("RunSetupFile Error", "Unknown file extension : " & $szExt)
	Exit
EndFunc
;----------------------------------------------------------------------
; Public Function
;  - GetSetupPath
;  - CheckSetupFile
;----------------------------------------------------------------------
Func GetSetupPath($SetupFile)
	Return GetSetupFileDirectory() & $SetupFile
EndFunc

Func CheckSetupFile($SetupFile)
	Dim $SetupPath	= GetSetupPath($SetupFile)
	
	Dim $bFileExists = FileExists($SetupPath)
	If Not $bFileExists Then
		$bFileExists = Download($SetupFile)
		If $bFileExists = True Then
			$RemoveAfterInstallSuccess = True
		EndIf
	EndIf
	Return $bFileExists
EndFunc
	
;----------------------------------------------------------------------
; Helper Function for downloading file
;  - Download
;  - GetWgetPath
;  - GetWgetOption
;  - GetWgetUrl
;  - GetWgetParameters
;----------------------------------------------------------------------
Func Download($SetupFile)
	Dim $WgetPath = GetWgetPath()
	
	Dim $WgetParameters = GetWgetParameters($SetupFile)
	Dim $Command = $WgetPath & $WgetParameters 		
	Dim $WgetWorkingDir = GetSetupFileDirectory()
	logInfo("Download", "RunWait(" & $Command & ", " & $WgetWorkingDir & ")")
	Dim $retCode = RunWait($Command, $WgetWorkingDir)
	
	; $retCode {Success = 0, Failure = 1}
	If $retCode <> 0 Then
		logError("Download", "Download process fails, please check " & $Command & " is correct")
		Return False
	EndIf

	Dim $SetupPath = GetSetupPath($SetupFile)
	If Not FileExists($SetupPath) Then
		logError("Download", "Can't find " & $SetupPath)
		Return False
	Else
		logInfo("Download", "Download file( " & $SetupPath & " ) Successfully")
		Return True
	EndIf
EndFunc



;----------------------------------------------------------------------
; Helper Function for GetSetupFile
;----------------------------------------------------------------------
Func GetDefaultAction()
	;{Install, Uninstall}
	Dim $DefaultAction = ""
	If $DefaultIsInstall Then
		$DefaultAction = "Install"
	Else
		$DefaultAction = "Uninstall"
	EndIf
	Return $DefaultAction
EndFunc

Func GetWinGetDirectory()
	$WinGetDir = RegRead("HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Environment", "WinGetDir")
	If $WinGetDir = "" And @error <> 0 Then
		logError("GetWinGetDirectory", "WinGetDir is not defined in HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Environment")
		Exit
	EndIf
	
	If Not FileExists($WinGetDir) Then
		logError("GetWinGetDirectory", "The WinGetDir( " & $WinGetDir & " ) not exists")
		Exit
	EndIf

	Return MakeSurePathHaveSlash($WinGetDir)
EndFunc

Func MakeSurePathHaveSlash($Path) 
	Dim $SlashPath = $Path
	Dim $len = StringLen($SlashPath)
	Dim $LastCh = StringMid($SlashPath, $len, 1)
	If $LastCh <> '\' Then
		$SlashPath = $SlashPath & "\"
	EndIf
	Return $SlashPath
EndFunc

Func GetSetupFileDirectory()
	Dim $SetupFileDirectory = GetWinGetDirectory() & "Program" & "\"
	If Not FileExists($SetupFileDirectory) Then
		If DirCreate($SetupFileDirectory) = 0 Then 
			logError("GetSetupFileDirectory","There is an error creating the directory( " & $SetupFileDirectory & " )")
			Exit
		EndIf
	EndIf
	Return $SetupFileDirectory
EndFunc

Func GetExecutableDirectory()
	Dim $ExecutableDirectory = GetWinGetDirectory() & "Bin" & "\"
	If Not FileExists($ExecutableDirectory) Then
		If DirCreate($ExecutableDirectory) = 0 Then 
			logError("GetExecutableDirectory","There is an error creating the directory( " & $ExecutableDirectory & " )")
			Exit
		EndIf
	EndIf
	Return $ExecutableDirectory
EndFunc
Func GetWgetPath()
	Dim $WgetPath = GetExecutableDirectory() & "wget.exe"
	If Not FileExists($WgetPath) Then
		logError("GetWgetPath", $WgetPath & " not exists")
		Exit
	EndIf
	Return $WgetPath
EndFunc

Func GetWgetOption()
	Return " --ftp-user=" & $USER & " --ftp-password=" & $PASS
EndFunc

Func GetWgetUrl($FileName)
	Return  " ftp://" & $HOST & "/Software/" & $FileName
EndFunc

Func GetWgetParameters($SetupFile)
	Dim $WgetParameters = GetWgetOption() & GetWgetUrl($SetupFile)
	Return $WgetParameters
EndFunc

Func logDebug($func,$msg)
	$data = "[Debug][" & $func & "]" & $msg & @CRLF
	ConsoleWrite($data)
EndFunc

Func logInfo($func,$msg)
	$data = "[Info ][" & $func & "]" & $msg & @CRLF
	ConsoleWrite($data)
EndFunc

Func logError($func,$msg)
	$data = "[Error][" & $func & "]" & $msg & @CRLF
	ConsoleWrite($data)
	MsgBox(16, $func, $data, 3)
EndFunc

Func CheckBeforeInstall($InstallProgramPath, $InstallFolder)
   	If StringLen($InstallProgramPath) <> 0 And FileExists($InstallProgramPath) Then
   		logError("CheckBeforeInstall", "File already exists (" & $InstallProgramPath & ")")
   		Return False
   	EndIf

   	If StringLen($InstallFolder) <> 0  And FileExists($InstallFolder) Then
   		If Not DirRemove ( $InstallFolder, 1) Then
   			logError("CheckBeforeInstall", "We got errors while removing directory ( " & $InstallFolder & " )")
   			Return False
   		EndIf
   	EndIf
	
	Return True
EndFunc